#include <QCoreApplication>
#include "adaptvision.h"
#include "loging/Logger.h"
#include <QElapsedTimer>

SILICOOL_CREATE_LOGGING_CATEGORY(AdaptVisionUnitTest, "AdaptVisionUnitTest")

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QElapsedTimer timer;
    AdaptVision *vision = new AdaptVision();
    {
        qCInfo(AdaptVisionUnitTest()) << "------------------Check dongle-----------------";
        bool ret = vision->checkDongle();
        if (ret) {
            qCInfo(AdaptVisionUnitTest()) << "Dongle test pass";
        } else {
            qCInfo(AdaptVisionUnitTest()) << "Dongle test fail";
            return true;
        }
    }
    {
        qCInfo(AdaptVisionUnitTest()) << "------------------Start Generic NCC Template Matching Unit Test-----------------";
        QImage img("prConfig//testhole.jpg");
        QImage resultImage("prConfig//testhole.jpg");
        PRResultStruct prResultStruct;
        PRResultImageInfo prResultImageInfo;
        QVariantMap args;
        args["a"] = 1;
        args["b"] = 0.5;
        timer.start();
        bool ret = vision->performPr(img, "prConfig//testhole.avdata", AdaptVision::PrType::Generic_NCC_Template_Matching, 0.5, prResultImageInfo, prResultStruct, 1, 2, args);
        qCInfo(AdaptVisionUnitTest()) << " Time Elapsed: " << timer.elapsed();
        if (ret) {
            qCInfo(AdaptVisionUnitTest()) << "PRResult x:" << prResultStruct.x << " y:"
                                          << prResultStruct.y << " theta: " << prResultStruct.theta
                                          << "ori_x: " << prResultStruct.ori_x << " ori_y: " << prResultStruct.ori_y;
            qCInfo(AdaptVisionUnitTest()) << "PRResult Image Info rect_x: " << prResultImageInfo.rect_x << " rect_y: " << prResultImageInfo.rect_y
                                          << " rect_angle: " << prResultImageInfo.rect_angle;
            vision->drawResultImage(resultImage, prResultImageInfo);
            resultImage.save("unitTest1.jpg");
        } else {
            qCInfo(AdaptVisionUnitTest()) << "Unit Test 1 Fail";
        }
    }
    {
        qCInfo(AdaptVisionUnitTest()) << "------------------Start Edge Fitting Unit Test Col Index 0-----------------";
        QImage img("prConfig//test.jpg");
        QImage resultImage("prConfig//test.jpg");
        int colIndex = 0;
        PRResultStruct prResultStruct;
        PRResultImageInfo prResultImageInfo;
        QVariantMap args;

        timer.restart();
        bool ret = vision->performPr(img, "prConfig//test_edgeModel.avdata", AdaptVision::PrType::Edge_Template_Matching, 0.5, prResultImageInfo, prResultStruct, 0, colIndex, args);
        qCInfo(AdaptVisionUnitTest()) << " Time Elapsed: " << timer.elapsed();
        if (ret) {
            qCInfo(AdaptVisionUnitTest()) << "PRResult x:" << prResultStruct.x << " y:" << prResultStruct.y << " theta: "
                                          << prResultStruct.theta
                                          << "ori_x: " << prResultStruct.ori_x << " ori_y: " << prResultStruct.ori_y;
            qCInfo(AdaptVisionUnitTest()) << "PRResult Image Info rect_x: " << prResultImageInfo.rect_x << " rect_y: " << prResultImageInfo.rect_y
                                          << " rect_angle: " << prResultImageInfo.rect_angle << " prResult x: " << prResultImageInfo.result_x
                                          << " y: " << prResultImageInfo.result_y << " ori_x: " << prResultImageInfo.result_ori_x
                                          << " ori_y: " << prResultImageInfo.result_ori_y << " width: " << prResultImageInfo.rect_width << " height: "
                                          << prResultImageInfo.rect_height;
            vision->drawResultImage(resultImage, prResultImageInfo);
            resultImage.save("unitTest2.jpg");
        } else {
            qCInfo(AdaptVisionUnitTest()) << "Unit Test 2 Fail";
        }
    }

    {
        qCInfo(AdaptVisionUnitTest()) << "------------------Start Edge Fitting Unit Test Col Index 2-----------------";
        QImage img("prConfig//test.jpg");
        QImage resultImage("prConfig//test.jpg");
        int colIndex = 3;
        PRResultStruct prResultStruct;
        PRResultImageInfo prResultImageInfo;
        QVariantMap args;
        timer.restart();
        bool ret = vision->performPr(img, "prConfig//test_edgeModel.avdata", AdaptVision::PrType::Edge_Template_Matching, 0.5, prResultImageInfo, prResultStruct, 0, colIndex, args);
        qCInfo(AdaptVisionUnitTest()) << " Time Elapsed: " << timer.elapsed();
        if (ret) {
            qCInfo(AdaptVisionUnitTest()) << "PRResult x:" << prResultStruct.x << " y:" << prResultStruct.y << " theta: "
                                          << prResultStruct.theta
                                          << "ori_x: " << prResultStruct.ori_x << " ori_y: " << prResultStruct.ori_y;
            vision->drawResultImage(resultImage, prResultImageInfo);
            resultImage.save("unitTest3.jpg");
        } else {
            qCInfo(AdaptVisionUnitTest()) << "Unit Test 3 Fail";
        }
    }

    {
        qCInfo(AdaptVisionUnitTest()) << "------------------Start Edge Fitting Unit Test Col Index 2 (Repeat)-----------------";
        QImage img("prConfig//test.jpg");
        QImage resultImage("prConfig//test.jpg");
        int colIndex = 3;
        PRResultStruct prResultStruct;
        PRResultImageInfo prResultImageInfo;
        QVariantMap args;
        timer.restart();
        bool ret = vision->performPr(img, "prConfig//test_edgeModel.avdata", AdaptVision::PrType::Edge_Template_Matching, 0.5, prResultImageInfo, prResultStruct, 0, colIndex, args);
        qCInfo(AdaptVisionUnitTest()) << " Time Elapsed: " << timer.elapsed();
        if (ret) {
            qCInfo(AdaptVisionUnitTest()) << "PRResult x:" << prResultStruct.x << " y:" << prResultStruct.y << " theta: "
                                          << prResultStruct.theta
                                          << "ori_x: " << prResultStruct.ori_x << " ori_y: " << prResultStruct.ori_y;
            vision->drawResultImage(resultImage, prResultImageInfo);
            resultImage.save("unitTest3.jpg");
        } else {
            qCInfo(AdaptVisionUnitTest()) << "Unit Test 3 Fail";
        }
    }

    {
        qCInfo(AdaptVisionUnitTest()) << "------------------Start Edge Fitting Unit Test 4-----------------";
        QImage img("prConfig//unitTest4.jpg");
        QImage resultImage("prConfig//unitTest4.jpg");
        int colIndex = 0;
        PRResultStruct prResultStruct;
        PRResultImageInfo prResultImageInfo;
        QVariantMap args;
        timer.restart();
        bool ret = vision->performPr(img, "prConfig//unitTest4_edgeModel.avdata", AdaptVision::PrType::Edge_Template_Matching, 0.5, prResultImageInfo, prResultStruct, 0, colIndex, args);
        qCInfo(AdaptVisionUnitTest()) << " Time Elapsed: " << timer.elapsed();
        if (ret) {
            qCInfo(AdaptVisionUnitTest()) << "PRResult x:" << prResultStruct.x << " y:" << prResultStruct.y << " theta: "
                                          << prResultStruct.theta
                                          << "ori_x: " << prResultStruct.ori_x << " ori_y: " << prResultStruct.ori_y;
            vision->drawResultImage(resultImage, prResultImageInfo);
            resultImage.save("unitTest4.jpg");
        } else {
            qCInfo(AdaptVisionUnitTest()) << "Unit Test 4 Fail";
        }
    }

    {
        qCInfo(AdaptVisionUnitTest()) << "------------Start Read Dispense Path Unit Test------------------------";
        QString filename = "prConfig//dispensePath.avdata";
        QVector<QPointF> points = vision->readDispensePath(filename);
        for ( int j = 0; j < points.length(); ++j)
        {
            float x = points[j].x();
            float y = points[j].y();
            qInfo("Result: %d : x: %f y: %f", j, x, y);
        }
    }

    {
        qCInfo(AdaptVisionUnitTest()) << "------------------Start Edge Fitting Unit Test 5-----------------";
        QImage img("prConfig//unitTest6.jpg");
        QImage resultImage;
        int colIndex = 0;
        PRResultStruct prResultStruct;
        PRResultImageInfo prResultImageInfo;
        QVariantMap args;
        timer.restart();
        bool ret = vision->performPr(img, "prConfig//stCaliGlassPr_edgeModel.avdata", AdaptVision::PrType::Edge_Template_Matching, 0.5, prResultImageInfo, prResultStruct, 0, colIndex, args);
        qCInfo(AdaptVisionUnitTest()) << " Time Elapsed: " << timer.elapsed();
        if (ret) {
            qCInfo(AdaptVisionUnitTest()) << "PRResult x:" << prResultStruct.x << " y:" << prResultStruct.y << " theta: "
                                          << prResultStruct.theta
                                          << "ori_x: " << prResultStruct.ori_x << " ori_y: " << prResultStruct.ori_y;
            resultImage.save("unitTest6.jpg");
        } else {
            qCInfo(AdaptVisionUnitTest()) << "Unit Test 4 Fail";
        }
    }

    //Circle Edge Fitting Unit Test
    {
        qCInfo(AdaptVisionUnitTest()) << "------------------Start Circle Edge Fitting Unit--------------";
        QImage img("prConfig//hello_inputImage.jpg");
        QImage resultImage("prConfig//hello_inputImage.jpg");
        int colIndex = 0;
        PRResultStruct prResultStruct;
        PRResultImageInfo prResultImageInfo;
        QVariantMap args;
        timer.restart();
        bool ret = vision->performPr(img, "prConfig//hello_circleFittingModel.avdata", AdaptVision::PrType::Circle_Edge_Template_Matching, 0.5, prResultImageInfo, prResultStruct, 0, colIndex, args);
        qCInfo(AdaptVisionUnitTest()) << " Time Elapsed: " << timer.elapsed();
        if (ret) {
            qCInfo(AdaptVisionUnitTest()) << "PRResult x:" << prResultStruct.x << " y:" << prResultStruct.y << " theta: "
                                          << prResultStruct.theta
                                          << "ori_x: " << prResultStruct.ori_x << " ori_y: " << prResultStruct.ori_y
                                          << " radius: " << prResultImageInfo.radius;
            vision->drawResultImage(resultImage, prResultImageInfo);
            resultImage.save("unitTest6.jpg");
        } else {
            qCInfo(AdaptVisionUnitTest()) << "Unit Test 4 Fail";
        }
    }

    //GlueInspection Unit test
    {
        qCInfo(AdaptVisionUnitTest()) << "------------------Glue Inspection Unit Test--------------";
        QImage imgBefore("glueCheckData//before//1.jpg");
        QImage imgAfter("glueCheckData//after//1_d.jpg");
        QImage resultImage;
        double a, b , c;
        bool ret = vision->glueCheck(imgBefore, imgAfter, 1,  resultImage, a, b, c);
        if (ret) {
            qCInfo(AdaptVisionUnitTest()) << "a: " << a << " b: " << b << " c: " << c;
        } else {
            qCInfo(AdaptVisionUnitTest()) << "Glue Inspection Unit Test Fail";
        }
    }

    return a.exec();
}
